package com.org.oracle.service.impl;

import com.org.oracle.enums.AssistantType;
import com.org.oracle.factory.AssistantConfigFactory;
import com.org.oracle.mongodb.dto.PostgraduateRequestDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;

import java.time.LocalDate;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

@Service
@Slf4j
public class PostgraduateAssistantService {
    private final AssistantConfigFactory configFactory;
    private final ChatClient.Builder clientBuilder;

    // 使用ConcurrentMap管理会话内存
    private final ConcurrentMap<String, SessionData> sessionStore = new ConcurrentHashMap<>();

    // 添加内存监控指标
    private final AtomicLong cleanupCounter = new AtomicLong(0);
    public PostgraduateAssistantService(AssistantConfigFactory configFactory, 
                                      ChatClient.Builder clientBuilder) {
        this.configFactory = configFactory;
        this.clientBuilder = clientBuilder;
    }

    public Mono<String> handleRequest(PostgraduateRequestDTO request) {
        return Mono.fromSupplier(() -> {

            // 获取或创建对话内存
            SessionData data = sessionStore.computeIfAbsent(
                    request.getUid(),
                    k -> new SessionData(new InMemoryChatMemory())
            );
            // 更新访问时间
            data.updateAccessTime();
            ChatClient client = configFactory.configureAssistant(
                    clientBuilder,
                    AssistantType.valueOf(request.getAssistantType()),
                    data.chatMemory
            );

            return client.prompt()
                    .system(s -> s
                            .param("current_date", LocalDate.now().toString())
                            .param("current_time", LocalTime.now().format(DateTimeFormatter.ofPattern("HH:mm")))
                    )
                    .user(request.getMessage())
                    .call()
                    .content();
        }).onErrorResume(e -> Mono.just("服务暂时不可用，请稍后重试"));
    }

//    @Scheduled(fixedDelay = 3600000)
//    public void cleanupMemories() {
//        sessionStore.keySet().removeIf(sessionId ->
//                System.currentTimeMillis() - sessionStore.get(sessionId).lastAccessTime > 7200000
//        );
//    }
    @Scheduled(fixedDelay = 3600000)// 每小时执行一次
    public void cleanupMemories() {
        long start = System.currentTimeMillis();
        final long threshold = 7200000; // 2小时

        // 安全删除方案
        List<String> toRemove = sessionStore.entrySet().stream()
                .filter(entry ->
                        System.currentTimeMillis() - entry.getValue().lastAccessTime > threshold)
                .map(Map.Entry::getKey)
                .toList();

        int removedCount = 0;
        for (String sessionId : toRemove) {
            if (sessionStore.remove(sessionId) != null) {
                removedCount++;
            }
        }

        cleanupCounter.addAndGet(removedCount);
        log.info("清理完成，移除{}个会话，耗时{}ms",
                removedCount, System.currentTimeMillis() - start);
    }
    // 会话数据包装类
    private static class SessionData {
        private final ChatMemory chatMemory;
        private long lastAccessTime;

        SessionData(ChatMemory chatMemory) {
            this.chatMemory = chatMemory;
            this.lastAccessTime = System.currentTimeMillis();
        }

        void updateAccessTime() {
            this.lastAccessTime = System.currentTimeMillis();
        }
    }
}